#include <stdio.h>
#include <stdlib.h>
#include "list.h"

// the list contain a header

struct node
{
	int element;
	position next;
};

list createList(int length, int* a)
{
	printf("call createList\n");
	list l;
	list list_node;
	//l->next = NULL;
	// the head_node:
	list_node = (list) malloc(sizeof(node));
	l = list_node;
	l -> next = NULL;	
	if(length >= 1) 
	{
		position p;
	// other node
		p = l;
		for (int i = 0; i < length; ++i)
		{
			printf("start \n");
			list_node = (list) malloc(sizeof(node));
			list_node -> element = a[i];
			p -> next = list_node;
			p = list_node;
			printf("create %d\n", i);
		}
		p -> next = NULL;
	}
	return l;
}

void printList(list l)
{
	printf("Call printList\n");
	position p;
	if (!isEmpty(l))
	{
		printf("list is not empty\n");
		p = l ->next;
		while(p -> next != NULL)
		{
			printf("%d\n", p -> element);
			p = p ->next;
		}
		printf("%d\n", p -> element);
	}
	
}

int getListLength(list l)
{
	position p;
	int len = 0;
	p = l;
	while( p -> next != NULL)
	{
		len++;
		p = p -> next;
	}
	return len;
}

list makeEmpty(list l)
{
	return NULL;
}

bool isEmpty(list l)
{
	if(l ->next == NULL)
		return true;
	else
		return false;
}

bool isLast(position p,list l)
{
	if (p -> next == NULL)
		return true;
	else return false;
}

position find(int x, list l)
{
	position p;
	if(isEmpty(l))
		return NULL;
	p = l -> next;
	while(p -> element != x && p != NULL)
	{
		p = p -> next;
	}
	printf("find %d\n", p);
	return p;
}

void deleteitem(int x, list l)
{
	position p;
	position temp;
	p =  findPrevious(x ,l);
	if(! isLast(p, l))
	{
		temp = p -> next;
		p -> next = temp -> next;
		free(temp);
	}

}
void deleteList(list l)
{
	position p, temp;
	p = l;
	while(p != NULL)
	{
		temp = p;
		p = p -> next;
		free(temp);
	}

}

position findPrevious(int x, list l)
{
	position p;
	if(isEmpty(l))
		return l;

	p = l;
	while((p -> next )-> element != x && (p ->next) != NULL)
	{
		p = p -> next;
	}
	return p;
}

void insert(int x, list l, position p)
{
	printf("call insert function inserting %d\n", x);
	position new_position;
	new_position = (list)malloc(sizeof(node));
	new_position -> element = x;
	new_position -> next = p ->next;
	p -> next = new_position;
    printf("inserting finished\n");
	
}

position header(list l)
{
	return l;
}

position first(list l)
{
	return l;
}

position advance(position p)
{
	return NULL;
}

int retrieve(position p)
{
	return 0;
}

list get_operation_or(list l1, list l2)
{
    if(isEmpty(l1))
        return l2;
    if(isEmpty(l2))
        return l1;
    list l3;
    int* a;
    position p, p1, p2;
    l3 = createList(0, a);
    p = l3;
    p1 = l1->next;
    p2 = l2->next;
    // and one is over then another
    while(p1 && p2)
    {
        if(p1->element < p2->element)
        {
            insert(p1->element, l3, p);
            p = p->next;
            p1 = p1->next;
        }
        else if(p1->element > p2->element)
        {
            insert(p2->element, l3, p);
            p = p->next;
            p2 = p2->next;
        }
        else
        {
            insert(p2->element, l3, p);
            p = p->next;
            p2 = p2->next;
            p1 = p1->next;
        }
    }

    while(p1)
    {
    	insert(p1->element, l3, p);
        p = p->next;
        p1 = p1->next;
    }
    
    while(p2)
    {
    	insert(p2->element, l3, p);
        p = p->next;
        p2 = p2->next;
    }
    return l3;
}

list get_operation_and(list l1, list l2)
{
    list l3;
    int* a;
    l3 = createList(0, a);
    if(isEmpty(l1) or isEmpty(l2))
    	return l3;

    position p, p1, p2;    
    p = l3;
    p1 = l1->next;
    p2 = l2->next;
    // and one is over then another
    while(p1 && p2)
    {
        if(p1->element < p2->element)
        {
            p1 = p1->next;
        }
        else if(p1->element > p2->element)
        {
            p2 = p2->next;
        }
        else
        {
            insert(p2->element, l3, p);
            p = p->next;
            p2 = p2->next;
            p1 = p1->next;
        }
    }
    return l3;
}